package com.ming.transaction.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ming.transaction.common.Result;
import com.ming.transaction.entity.Icon;
import com.ming.transaction.entity.Menu;
import com.ming.transaction.mapper.IconMapper;
import com.ming.transaction.mapper.MenuMapper;
import com.ming.transaction.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.ming.transaction.common.Constant.*;

/**
 * <p>
 *      菜单管理实现类
 * </p>
 *
 * @author 陈仕健
 * @since 2023-05-06
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    @Resource
    private IconMapper iconMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 子查询 、 查询子菜单数据
     * @return
     */
    @Override
    public List<Menu> findAll() {
        String ls = stringRedisTemplate.opsForValue().get(MENU_LIST);
        if ( StrUtil.isNotBlank(ls) ){
            List<Menu> list = JSONUtil.toList(ls,Menu.class);
            // 找出 pid 为 null 的一级菜单
            List<Menu> parentNode = list.stream().filter(menu -> menu.getPid() == null).collect(Collectors.toList());
            // 找出一级菜单的子菜单
            for (Menu menu : parentNode) {
                // 筛选所有数据中的 pid = 父级 id 的数据就是二级菜单
                menu.setChildren(list.stream().filter( m -> menu.getId().equals(m.getPid())).collect(Collectors.toList()));
            }
            return parentNode;
        }
        // 查询所有数据
        List<Menu> list = list();
        stringRedisTemplate.opsForValue().set(MENU_LIST,JSONUtil.toJsonStr(list));
        // 找出 pid 为 null 的一级菜单
        List<Menu> parentNode = list.stream().filter(menu -> menu.getPid() == null).collect(Collectors.toList());
        // 找出一级菜单的子菜单
        for (Menu menu : parentNode) {
            // 筛选所有数据中的 pid = 父级 id 的数据就是二级菜单
            menu.setChildren(list.stream().filter( m -> menu.getId().equals(m.getPid())).collect(Collectors.toList()));
        }
        return parentNode;
    }

    /**
     * 查询图标
     * @return
     */
    @Override
    public Object selectIcon() {
        String icon = stringRedisTemplate.opsForValue().get(ICONS_LIST);
        if (StrUtil.isNotBlank(icon)){
            List<Icon> icons = JSONUtil.toList(icon,Icon.class);
            return icons;
        }
        QueryWrapper<Icon> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type",TYPE_ICON);
        List<Icon> icons = iconMapper.selectList(queryWrapper);
        stringRedisTemplate.opsForValue().set(ICONS_LIST,JSONUtil.toJsonStr(icons),ICONS_LIST_TTL, TimeUnit.HOURS);
        return icons;
    }

    /**
     * 管理员添加菜单
     * @param menu
     * @return
     */
    @Override
    public Result saveMenu(Menu menu) {
        boolean savemenu = save(menu);
        if(!savemenu){
            return Result.fail("添加菜单失败!");
        }
        String menus = stringRedisTemplate.opsForValue().get(MENU_LIST);
        List<Menu> menusl = JSONUtil.toList(menus,Menu.class);
        menusl.add(menu);
        stringRedisTemplate.opsForValue().set(MENU_LIST,JSONUtil.toJsonStr(menusl));
        return Result.success("添加成功菜单！");
    }

    /**
     * 管理员更新菜单
     * @param menu
     * @return
     */
    @Override
    public Result updateMenu(Menu menu) {
        boolean upmenu = saveOrUpdate(menu);
        if ( !upmenu ){
            return Result.fail("修改菜单失败!");
        }
        List<Menu> list = list();
        stringRedisTemplate.opsForValue().set(MENU_LIST,JSONUtil.toJsonStr(list));
        return Result.success("修改菜单成功！");
    }

    /**
     * 管理员删除菜单
     * @param id
     * @return
     */
    @Override
    public Result deleteById(Integer id) {
        boolean remo = removeById(id);
        if (!remo){
            return Result.fail("删除菜单失败!");
        }
        List<Menu> list = list();
        stringRedisTemplate.opsForValue().set(MENU_LIST,JSONUtil.toJsonStr(list));
        return  Result.success("删除菜单成功!");
    }

    /**
     * 管理员批量删除菜单
     * @param ids
     * @return
     */
    @Override
    public Result deleteByIds(List<Integer> ids) {
        boolean remos = removeByIds(ids);
        if (!remos){
            return Result.fail("批量删除菜单失败!");
        }
        List<Menu> list = list();
        stringRedisTemplate.opsForValue().set(MENU_LIST,JSONUtil.toJsonStr(list));
        return  Result.success("批量删除菜单成功!");
    }


}
